package com.zls.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * 配置用户名和密码
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //密码加密
//        String encode = passwordEncoder.encode("123456");
//        System.out.println(encode);
        //基于内存保存用户名和密码
//        auth.inMemoryAuthentication().withUser("root").password(encode).roles();
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    //自定义登录页
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //1.关闭csrf跨站伪造请求
        //security认为只要不是它本身提供的页面资源，就是非法的
        http.csrf().disable();

        //2.自定义登录表单
        http.formLogin()
                .loginPage("/login.html") //指定登录页
                .loginProcessingUrl("/user/login") //登录的请求URL
                .defaultSuccessUrl("/index.html")//如果直接访问登录页，未指定目标资源，登录成功后去的目标资源
                //指定页面用户名的name属性和密码的name属性，默认就是username和password
                //.usernameParameter().passwordParameter()
                //放行
                .permitAll();

        //8.登出
        http.logout()
                .logoutUrl("/user/logout") //退出url
                .logoutSuccessUrl("/login.html")//退出后去哪
                //杀死session
                .invalidateHttpSession(true)
                //删除cookie
                .deleteCookies("JSESSIONID");

        //4.指定放行的资源。要写在所有认证通过的请求前面
        http.authorizeRequests()
                //指定放行资源的规则
                .antMatchers("/", "/show/name", "/user/register")
                .permitAll();

        //6.基于权限控制访问权限
        http.authorizeRequests()
                .antMatchers("/student/update")
                .hasAuthority("update");

        //5.基于角色控制访问权限
        http.authorizeRequests()
                //具备 student 或者 admin 这个角色才能访问 /student/** 的资源。
                .antMatchers("/student/**")
                //在这个API中会自动帮我们加上 ROLE_ 前缀
                //如果没有对应的角色，就无法访问到目标资源，会报 403 【权限不足】
                .hasAnyRole("student", "admin");

        //7.处理403
        http.exceptionHandling().accessDeniedPage("/403.html");

        //3.拦截规则【一定要指定】放最后
        http.authorizeRequests()
                .anyRequest()//任意请求
                .authenticated(); //认证通过


    }
}
